//################################################################################
// MIT License
// Copyright (c) 2024 ZhangYihua
//
// Change Logs:
// Date           Author       Notes
// 2020-12-20     ZhangYihua   first version
//
// Description  : 
//################################################################################

module cos_sin_wave #(
parameter           WAVE_DW                 = 12,
parameter           WAVE_AM                 = 2047,     // WAVE_AM < 2^(WAVE_DW-1)
parameter           NEG_SIN                 = 1'b0,     // 1'b0:normal; 1'b1:invert sin;
parameter           NCO_DW                  = 16,
parameter           PHS_DW                  = 11        // 3< PHS_DW <=NCO_DW
) ( 
input                                       rst_n,
input                                       clk,
input                                       cke,

input       signed  [NCO_DW-1:0]            freq_word,  // output frequency is F_clk*freq_word/(2^NCO_DW)

output  reg signed  [WAVE_DW-1:0]           cos_dat,
output  reg signed  [WAVE_DW-1:0]           sin_dat
);

//################################################################################
// define local varialbe and localparam
//################################################################################
wire                [PHS_DW-1:0]            phase;

//################################################################################
// main
//################################################################################

nco #(
        .PHS_FW                         (PHS_DW                         ),
        .NCO_FW                         (NCO_DW                         ),
        .FREQ_DW                        (NCO_DW                         ),	// FREQ_DW<=NCO_FW or FREQ_DW>NCO_FW is both OK
        .RND_EN                         (1'b1                           )	// 1'b0:truncate lower bits directly; 1'b1:rounding, but over_1p is not used in this mode
) u_nco ( 
        .rst_n                          (rst_n                          ),
        .clk                            (clk                            ),
        .cke                            (cke                            ),

        .freq_word                      (freq_word                      ),	// output frequency is F_clk*freq_word/(2^ACC_DW)

        .over_1p                        (                               ),	// combinational logic output
        .phase                          (phase                          )   // it's maybe early than acc_over if RDN_EN=1'b1
);

cos_sin_tab #(
        .WAVE_DW                        (WAVE_DW                        ),
        .WAVE_AM                        (WAVE_AM                        ),	// WAVE_AM < 2^(WAVE_DW-1)
        .NEG_SIN                        (NEG_SIN                        ),	// 1'b0:normal; 1'b1:invert sin;
        .PHS_DW                         (PHS_DW                         ),
        .CH_NUM                         (1                              )
) u_cos_sin_tab ( 
        .rst_n                          (rst_n                          ),
        .clk                            (clk                            ),
        .cke                            (cke                            ),

        .phase                          (phase                          ),	// (0:2*PI)
        .cos_dat                        (cos_dat                        ),	// [-WAVE_AM:WAVE_AM]
        .sin_dat                        (sin_dat                        )	// [-WAVE_AM:WAVE_AM]
);

//################################################################################
// ASSERTION
//################################################################################

`ifdef CBB_ASSERT_ON
// synopsys translate_off


// synopsys translate_on
`endif

endmodule
